package ypmits.components.listbox.view {
	import ypmits.bitmap.BitmapModifierTool;
	import ypmits.components.buttons.CloseButton;
	import ypmits.components.buttons.event.ButtonEvent;
	import ypmits.components.listbox.ScrollBarWrapper;
	import ypmits.components.listbox.button.ListBoxButton;
	import ypmits.components.listbox.button.ListBoxButtonData;
	import ypmits.components.listbox.input.ListBoxInput;
	import ypmits.components.listbox.view.item.ListBoxItem;
	import ypmits.components.listbox.view.item.ListBoxItemData;
	import ypmits.components.util.TextFieldUtility;
	import ypmits.effects.FilterEffects;
	import ypmits.font.Arial;
	import ypmits.setup.EasySetup;
	import ypmits.simpledraw.Square;

	import flash.display.Bitmap;
	import flash.display.InterpolationMethod;
	import flash.display.Shape;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	/**
	 * @author Dave Lenz
	 */
	public class ListBoxView extends Sprite {
		public static const TITLEHEIGHT : Number = 22;
		public static const GRABBERHEIGHT : Number = 6;
		
		public var content : Sprite;
		public var grabber : Sprite;
		public var currentitem : ListBoxItem;
		
		private var _itemsarray : Array = new Array( );
		private var _hasdrawn : Boolean = false;
		private var input : ListBoxInput;
		private var _background : Shape;
		private var header : Square;
		private var _masker : Sprite;
		private var _grabberinvis : Sprite;
		private var rand : Sprite;
		private var titletextfield : TextFieldUtility;
		private var _scrollbar : ScrollBarWrapper;
		private var _grabthumb : Sprite;
		private var closebutton : CloseButton;
		private var buttons : Array = new Array();
		private var warning : ListBoxWarning;

		
		
		public function ListBoxView( data : ListBoxInput ) {
			input = data;

			draw( );
			
			mouseEnabled = false;
			mouseChildren = true;
		}

		
		private function draw() : void {
			if( input.background ) {
				_background = new Shape( );
				_background.graphics.beginFill( input.backgroundcolor, input.backgroundalpha );
				_background.graphics.drawRect( 0, 0, input.width, input.height );
				addChild( _background );
			}
			
			header = new Square( input.width, TITLEHEIGHT, [ 0x555555, 0x000000 ], [ 1, 1 ], [ 0, 0xFF ], 90, null, SpreadMethod.PAD, InterpolationMethod.RGB, 0 );
			header.setBorder( 1, 0, 1, [false,false,true,false] );
			addChild( header );
			
			titletextfield = new TextFieldUtility( input.title, new Arial().fontName, 11, 0, false, input.titlealign );
			titletextfield.x = 7;
			titletextfield.y = 3;
			titletextfield.sharpness = 0;
			header.addChild( titletextfield );
			
			FilterEffects.makeColor( titletextfield, 0xFFFFFF );

			content = new Sprite( );
			content.y = TITLEHEIGHT;
			content.mouseEnabled = true;
			content.mouseChildren = true;
			addChild( content );
			
			_masker = new Sprite( );
			_masker.graphics.clear( );
			_masker.graphics.beginFill( 0xFF0000, 1 );
			_masker.graphics.drawRect( 0, 0, input.width, input.height - TITLEHEIGHT );
			_masker.graphics.endFill( );
			_masker.y = TITLEHEIGHT;
			addChild( _masker );
			
			/**
			 * ==============================================
			 * LET'S CHECK IF THE LISTBOX SHOULD BE RESIZABLE
			 * ==============================================
			 */
			if( input.resizable ) {
				grabber = new Sprite( );
				grabber.graphics.lineStyle( 1, input.bordercolor, 1, true );
				grabber.graphics.beginFill( 0x222222, 1 );
				grabber.graphics.drawRect( 0, 0, input.width, GRABBERHEIGHT );
				grabber.y = input.height - GRABBERHEIGHT;
				addChild( grabber );

				var shape : Shape = new Shape( );
				shape.graphics.beginFill( 0xFFFFFF, 1 );
				shape.graphics.drawRect( 0, 0, 1, 1 );
				shape.graphics.drawRect( 1, 2, 1, 1 );

				_grabthumb = new Sprite( );
				_grabthumb.graphics.beginBitmapFill( BitmapModifierTool.convertToBitmap( shape, shape.width, shape.height, false ).bitmapData, null, true, false );
				_grabthumb.graphics.drawRect( 0, 0, 11, 3 );
				_grabthumb.graphics.endFill( );
				_grabthumb.x = ( input.width * .5 ) - 5;
				_grabthumb.mouseEnabled = false;
				_grabthumb.y = 2;

				grabber.addChild( _grabthumb );
			
				_grabberinvis = new Sprite( );
				_grabberinvis.graphics.beginFill( 0xFF9900, 0 );
				_grabberinvis.graphics.drawRect( 0, -3, input.width, GRABBERHEIGHT + 6 );
				_grabberinvis.y = input.height - GRABBERHEIGHT;
				_grabberinvis.addEventListener( MouseEvent.MOUSE_DOWN, grabHandler );
				_grabberinvis.buttonMode = true;
				addChild( _grabberinvis );
			}

			rand = new Sprite( );
			rand.mouseEnabled = false;
			if( input.border ) addChild( rand );
			
			_scrollbar = new ScrollBarWrapper( content, 100 );
			_scrollbar.y = TITLEHEIGHT + 4;
			addChild( _scrollbar );
			
			if( input.buttons && input.buttons.length > 0 ) {
				input.spacearoundscrollbar <= 3 ? input.spacearoundscrollbar = 100 : null;
				var h : Number = TITLEHEIGHT + 4;
				for (var i : int = 0; i < input.buttons.length; i++) {
					var buttondata : ListBoxButtonData = ListBoxButtonData( input.buttons[i] );
					var button : ListBoxButton = new ListBoxButton( buttondata );
					button.x = input.width - input.spacearoundscrollbar + 3;
					button.y = h;
					button.width = input.spacearoundscrollbar - 6;
					h += button.height + 4;
					addChild( button );
					buttons.push( button );
				}
			}
			
			if( input.closebutton ) {
				closebutton = new CloseButton();
				closebutton.scaleX = closebutton.scaleY = .6;
				closebutton.addEventListener( ButtonEvent.MOUSE_OVER, mouseHandler );
				closebutton.addEventListener( ButtonEvent.MOUSE_OUT, mouseHandler );
				closebutton.addEventListener( MouseEvent.CLICK, mouseHandler );
				closebutton.x = input.width;
				addChild( closebutton );
			}
			
			warning = new ListBoxWarning();
			addChild( warning );

			redraw( );
		}

		
		public function addItem( item : ListBoxItemData ) : void {
			_itemsarray.push( item );
			redraw( );
		}

		
		public function addItems( items : Array) : void {
			for (var i : int = 0; i < items.length; i++) {
				_itemsarray.push( items[i] );
			}
			redraw( );
		}

		
		private function mouseHandler( e : Event ) : void {
			if( e.type == ButtonEvent.MOUSE_OVER ) {
				ButtonEvent( e ).displayobject.rotation = 45;
			} else if( e.type == ButtonEvent.MOUSE_OUT ) {
				ButtonEvent( e ).displayobject.rotation = -45;
			} else if( e.type == MouseEvent.CLICK ) {
				dispatchEvent( new Event( Event.CLOSE ) );
			}
		}

		
		private function grabHandler( e : MouseEvent ) : void {
			if( e.type == MouseEvent.MOUSE_DOWN ) {
				addEventListener( Event.ENTER_FRAME, enterFrameHandler );
				_grabberinvis.startDrag( false, new Rectangle( 0, input.height - GRABBERHEIGHT, 0, 400 ) );
				_grabberinvis.removeEventListener( MouseEvent.MOUSE_DOWN, grabHandler );
				EasySetup.instance.stage.addEventListener( MouseEvent.MOUSE_UP, grabHandler );
			} else if ( e.type == MouseEvent.MOUSE_UP ) {
				_grabberinvis.stopDrag( );
				_grabberinvis.addEventListener( MouseEvent.MOUSE_DOWN, grabHandler );
				EasySetup.instance.stage.removeEventListener( MouseEvent.MOUSE_UP, grabHandler );
				removeEventListener( Event.ENTER_FRAME, enterFrameHandler );
				redraw( );
			}
		}

		
		private function enterFrameHandler( e : Event ) : void {
			redraw( );
		}

		
		public function redraw( complete : Boolean = false ) : void {
			if( input.border ) {
				rand.graphics.clear( );
				rand.graphics.beginFill( input.bordercolor );
				rand.graphics.drawRect( 0, 0, input.width, ( input.resizable ? _grabberinvis.y : (input.height - GRABBERHEIGHT) ) + GRABBERHEIGHT );
				rand.graphics.drawRect( 1, 1, input.width - 2, ( input.resizable ? _grabberinvis.y - 2 : (input.height - GRABBERHEIGHT) ) + GRABBERHEIGHT - 2 );
				rand.graphics.endFill();
			}

			if( !_hasdrawn ) {
				if( content ) {
					while( content.numChildren > 0 ) {
						content.removeChild( content.getChildAt( 0 ) );
					}
					var item : ListBoxItem;
					var i : int = 0;
					for ( ; i < _itemsarray.length; i++ ) {
						item = new ListBoxItem( input.width - input.spacearoundscrollbar - 10, ListBoxItemData( _itemsarray[i] ) );
						item.addEventListener( MouseEvent.CLICK, listboxClickHandler );
						item.y = i * item.height;
						content.addChild( item );
					}
				}
			
				if( complete ) _hasdrawn = true;
			}

			_masker ? _masker.height = ( input.resizable ? _grabberinvis.y : (input.height) ) - TITLEHEIGHT : null;
			content ? content.mask = _masker : null;
			input.resizable ? ( grabber ? grabber.y = _masker.y + _masker.height : null ) : null;
			_background ? _background.height = (input.resizable ? grabber.y : (input.height - GRABBERHEIGHT) ) + GRABBERHEIGHT : null;
			
			if( _scrollbar ) {
				_scrollbar.x = content.x + content.width - 7;
				_scrollbar.update( (input.resizable ? grabber.y : (input.height - GRABBERHEIGHT) ) - TITLEHEIGHT - GRABBERHEIGHT, content.height );
			}

			dispatchEvent( new Event( Event.RESIZE ) );
		}

		
		
		private function listboxClickHandler( e : MouseEvent ) : void 
		{
  			if( currentitem ) currentitem.deselect();
			currentitem = ListBoxItem( e.currentTarget );
			currentitem.select();
			dispatchEvent( new Event( Event.CHANGE, true, true ) );
		}

		
		
		public function dispose() : void 
		{
			_grabberinvis.removeEventListener( MouseEvent.MOUSE_DOWN, grabHandler );
			closebutton.removeEventListener( ButtonEvent.MOUSE_OVER, mouseHandler );
			closebutton.removeEventListener( ButtonEvent.MOUSE_OUT, mouseHandler );
			closebutton.removeEventListener( MouseEvent.CLICK, mouseHandler );
			removeEventListener( Event.ENTER_FRAME, enterFrameHandler );
			parent.removeChild( this );
		}

		
		
		override public function get height() : Number 
		{
			return rand.height;
		}

		
		
		override public function get numChildren() : int 
		{
			return _itemsarray.length;
		}

		
		
		public function showListBoxWarning( text : String ) : void 
		{
			warning.setText( text );
			
			warning.x = (width * .5) - (warning.width * .5);
			warning.y = (height * .5) - (warning.height * .5);
			warning.show( );
			
			var i : int = 0;
			for( ; i < buttons.length; i++) {
				ListBoxButton( buttons[i] ).visible = false;
			}
		}

		
		
		public function hideListBoxWarning() : void 
		{
			warning.hide();
			var i : int = 0;
			for( ; i < buttons.length; i++) {
				ListBoxButton( buttons[i] ).visible = true;
			}
		}
	}
}
